#pragma once

//
// Table field types
//
#define TFT_INT				0x01
#define TFT_LNG				0x02
#define TFT_DBL				0x03
#define TFT_STR				0x04
#define TFT_BIN				0x05


class CEX TableFieldBase:public Object
{
	// The table the field is part of
	class Table* _table;

	// Field name
	String _name;

	// Field type
	int _type;

	// Field size
	int _size;

	// Field offset within the data file
	int _offset;


	// Old field data, when a maintenance is in progress
	int _oldType;
	int _oldSize;
	int _oldOffset;

	friend class DB;
	friend class Table;

public:
	
	virtual const char* __getName(){return "TableFieldBase";}

	TableFieldBase()
	{
	}

	~TableFieldBase()
	{
	}

};

template<class T> class CEX TableField:public TableFieldBase
{
	// Field value
	T _val;

	friend class DB;
	friend class Table;

public:

	virtual const char* __getName(){return "TableField";}

	TableField()
	{
	}

	~TableField()
	{
	}

	TableField<T>& operator=(const T& val)
	{
		_val = val;

		return *this;
	}

	operator T() const
	{
		return _val;
	}
};



struct TableFieldDef
{
	int _type;
	int _size;
	int _offset;
	char _name[32];
};


class CEX Table:public Object
{
	// All the registered fields
	Array<TableFieldBase*> _fields;

	// The base path of the table
	String _basePath;
	String _baseBackupPath;


	void backup();
	void loadDef();
	void validateDef(Buffer& buf);
	void fixAll();
	void fixData(TableFieldDef* defs);

	friend class DB;
	friend class TableFieldBase;

protected:

	// The table definition
	Table* _tableDef;

	Table();
	Table(Table* tableDef);

public:
	
	virtual const char* __getName(){return "Table";}

	~Table();
	

	virtual String getName() = 0;

	void registerField(TableFieldBase* field,const String& name,int type,int size);

	// Commit an insert or an update
	void commit();
};

